package net.yxsoft.kit;

import java.security.InvalidKeyException;
import java.security.Key;
import java.security.Security;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;

import org.bouncycastle.crypto.digests.SM3Digest;
import org.bouncycastle.crypto.macs.HMac;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.encoders.Hex;

/**
 * 
 * @author Ray
 * @version 20201201110000
 */
public class SM234Util {
	
	static {
        if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null){
            Security.addProvider(new BouncyCastleProvider());
        }
    }

	/**
	 * 
	 * @param sm4Key(密钥)
	 * @param msg(待加密字符串)
	 * @return
	 * @throws Exception
	 */
	public static String sm4Encrypt(String sm4Key, String msg) throws Exception {
		byte[] keyBytes = sm4Key.getBytes("UTF-8");
		if (keyBytes.length != 16){
			throw new RuntimeException("密钥长度不合法");
		}
		byte[] msgBytes = msg.getBytes("UTF-8");
		Key key = new SecretKeySpec(keyBytes, "SM4");
		Cipher c = Cipher.getInstance("SM4/ECB/PKCS7Padding", BouncyCastleProvider.PROVIDER_NAME);
		c.init(Cipher.ENCRYPT_MODE, key);
		return Hex.toHexString(c.doFinal(msgBytes)).toUpperCase();
	}
	
	/**
	 * 
	 * @param sm4Key(密钥)
	 * @param msg(待解密字符串)
	 * @return
	 * @throws Exception
	 */
	public static String sm4Decrypt(String sm4Key, String msg)  {
		try {
		byte[] msgBytes = Hex.decode(msg);
		if (msgBytes.length % 16 != 0){
			throw new RuntimeException("待解密字符串长度不合法");
		}
		byte[] keyBytes = sm4Key.getBytes("UTF-8");
		Key key = new SecretKeySpec(keyBytes, "SM4");
		Cipher c = Cipher.getInstance("SM4/ECB/PKCS7Padding", BouncyCastleProvider.PROVIDER_NAME);

			c.init(Cipher.DECRYPT_MODE, key);

		return new String(c.doFinal(msgBytes), "UTF-8");
		} catch (Exception e) {
		return msg;
		}
	}
	
	
	/**
	 * 
	 * @param sm3Key(密钥)
	 * @param msg(待加密字符串)
	 * @return
	 * @throws Exception
	 */
	public static String sm3Sign(String sm3Key, String msg) throws Exception {
		SM3Digest sm3Digest = new SM3Digest();
		byte[] b = msg.getBytes("UTF-8");
		byte[] result = null;
		if (sm3Key == null || "".equals(sm3Key)){
			sm3Digest.update(b, 0, b.length);
			result = new byte[sm3Digest.getDigestSize()];
			sm3Digest.doFinal(result, 0);
		} else {
			KeyParameter keyParameter = new KeyParameter(sm3Key.getBytes("UTF-8"));
			HMac hMac = new HMac(sm3Digest);
			hMac.init(keyParameter);
			hMac.update(b, 0, b.length);
			result = new byte[hMac.getMacSize()];
			hMac.doFinal(result, 0);
		}
		return Hex.toHexString(result).toUpperCase();
	}
	
}
